package chatroom;

import java.io.*;
import java.net.Socket;
import java.net.SocketException;

/**
 * 服务器端线程
 *
 * @Author: xxf
 * @CreateDate: 2020/9/4 19:11
 * 1.通过构造方法传入客户端socket对象，得到客户端输入输出流
 * 2.通过输入流read客户端信息给客户端注册一个用户名
 * 3.遍历客户端线程对象集合并输出信息
 * 4.再次接收客户端输入流信息判断1.群聊；2.退出；3.私聊；分别传给不同的对象
 */
public class ServerThread extends Thread {
    /**
     * 字符输入流
     */
    BufferedReader r;
    /**
     * 字符输出流
     */
    BufferedWriter w;

    /**
     * 通过构造方法将客户端的socket传过来,调用socket.getInputStream()/getOutputStream()获得socket输入输出流再转换成字节流
     *
     * @param socket1
     */
    public ServerThread(Socket socket1) {
        try {
            r = new BufferedReader(new InputStreamReader(socket1.getInputStream()));
            w = new BufferedWriter(new OutputStreamWriter(socket1.getOutputStream()));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @SuppressWarnings("all")
    @Override
    public void run() {
        try {

            //接收客户端控制台输入的用户名
            String clientName = r.readLine();
            //欢迎信息
            String welcomeMessage = "欢迎" + clientName + "进入聊天室";
            //将用户名设为此客户端线程的线程名称
            Thread.currentThread().setName(clientName);

            //将欢迎信息转发给所有用户
            ChatServer.clientThreads.stream().forEach((thread) -> {
                try {
                    thread.w.write(welcomeMessage);
                    thread.w.newLine();
                    thread.w.flush();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            });
            //增强for循环
//            for (ServerThread thread : ChatServer.clientThreads) {
//                thread.w.write(welcomeMessage);
//                thread.w.newLine();
//                thread.w.flush();
//            }

            //循环聊天
            while (true) {
                //接收客户端发的消息
                String recieveMessage = r.readLine();
                //判断消息是群聊还是私聊 --->私聊  @姓名#内容
                if (recieveMessage.startsWith("@")) {
                    //将私聊的内容进行拆分
                    String[] s = recieveMessage.substring(1).split("#");
                    //私聊用户名
                    String receiveName = s[0];
                    //私聊内容
                    String receiveWord = s[1];
                    String word2 = Thread.currentThread().getName() + "悄悄对你说:" + receiveWord;
                    //遍历集合转发给指定用户
                    for (ServerThread t1 : ChatServer.clientThreads) {
                        if (t1.getName().equals(receiveName)) {
                            t1.w.write(word2);
                            t1.w.newLine();
                            t1.w.flush();
                            break;
                        }
                    }
                    //用户输入exit即退出聊天室
                } else if ("exit".equals(recieveMessage.toLowerCase())) {
                    //手动抛异常给下面抓捕
                    throw new SocketException();
                    //群聊
                } else {
                    //客户端发送的消息
                    String word = Thread.currentThread().getName() + "说：" + recieveMessage;

                    //遍历集合把消息转发给每个用户
                    for (ServerThread t1 : ChatServer.clientThreads) {
                        t1.w.write(word);
                        t1.w.newLine();
                        t1.w.flush();
                    }
                }
            }
            //用户退出了就会抛出这个异常
        } catch (SocketException e1) {
            //退出信息
            String exitMessage = Thread.currentThread().getName() + "退出了聊天室!";

            //遍历集合,将线程退出消息发给所有用户
            try {
                for (ServerThread t1 : ChatServer.clientThreads) {
                    t1.w.write(exitMessage);
                    t1.w.newLine();
                    t1.w.flush();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

            //遍历线程集合,找到当前要退出线程对象删除
            for (int i = 0; i < ChatServer.clientThreads.size(); i++) {
                if (ChatServer.clientThreads.get(i).getName().equals(Thread.currentThread().getName())) {
                    //根据找到要删除的线程对象的索引,将当前线程对象从集合中删除
                    ChatServer.clientThreads.remove(i);
                    break;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
